home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
gepackte_disketten
/
1994
/
08_94_5.dms
/
08_94_5.adf
/
term-4.0-Source.lha
/
termTransfer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-01
|
35KB
|
1,739 lines
/*
** termTransfer.c
**
** File transfer routines
**
** Copyright © 1990-1994 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* The action strings to display. */
STATIC STRPTR SendQuery[3],
ReceiveQuery[3],
TransferTypes[3];
/* ReplaceName(STRPTR Original):
*
* Replace a filename with a mangled version for
* file uploads.
*/
STATIC STRPTR __regargs
ReplaceName(STRPTR Source)
{
if(Config -> TransferConfig -> MangleFileNames)
{
UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
strcpy(OriginalName,Source);
ShrinkName(FilePart(Source),LocalName,12,TRUE);
strcpy(ShrunkenName,Source);
Char = PathPart(ShrunkenName);
*Char = 0;
AddPart(ShrunkenName,LocalName,MAX_FILENAME_LENGTH);
return(ShrunkenName);
}
else
{
OriginalName[0] = 0;
return(Source);
}
}
/* FreeFileTransferInfo(struct FileTransferInfo *Info):
*
* Free a file transfer info list as allocated
* by AllocFileTransferInfo() and AddFileTransferNode().
*/
VOID __regargs
FreeFileTransferInfo(struct FileTransferInfo *Info)
{
if(Info)
{
struct FileTransferNode *Node,
*Next;
Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
{
FreeVecPooled(Node);
Node = Next;
}
FreeVecPooled(Info);
}
}
/* AllocFileTransferInfo():
*
* Allocate a FileTransferInfo structure for use with
* AddFileTransferNode().
*/
struct FileTransferInfo *
AllocFileTransferInfo()
{
struct FileTransferInfo *Info;
if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
{
NewList((struct List *)&Info -> FileList);
return(Info);
}
return(NULL);
}
/* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
*
* Allocate a file transfer information node.
*/
BYTE __regargs
AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
{
struct FileTransferNode *Node;
WORD Len = strlen(Name) + 1;
if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + Len,MEMF_ANY))
{
Node -> Size = Size;
Node -> Name = (STRPTR)(Node + 1);
strcpy(Node -> Name,Name);
AddTail((struct List *)&Info -> FileList,(struct Node *)Node);
Info -> TotalSize += Size;
Info -> TotalFiles++;
return(TRUE);
}
else
return(FALSE);
}
/* Compare(struct FileTransferNode **A,struct FileTransferNode **B):
*
* Local subroutine required by qsort().
*/
STATIC int __stdargs
Compare(struct FileTransferNode **A,struct FileTransferNode **B)
{
return(Stricmp(FilePart((*A) -> Name),FilePart((*B) -> Name)));
}
/* SortFileTransferInfo(struct FileTransferInfo *Info):
*
* Sorts the file transfer information list in ascending
* order, but makes sure that the files are sorted
* in descending order (i.e. the larger files come
* first and files of equal size are sorted
* lexically).
*/
VOID __regargs
SortFileTransferInfo(struct FileTransferInfo *Info)
{
if(Info -> TotalFiles > 1)
{
struct FileTransferNode **NodeList;
if(NodeList = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info -> TotalFiles,MEMF_ANY))
{
struct FileTransferNode *Node,
*Next;
LONG i = 0;
Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
{
NodeList[i++] = Node;
Node = Next;
}
qsort((APTR)NodeList,Info -> TotalFiles,sizeof(struct FileTransferNode *),Compare);
NewList((struct List *)&Info -> FileList);
for(i = 0 ; i < Info -> TotalFiles ; i++)
AddTail((struct List *)&Info -> FileList,(struct Node *)&NodeList[i] -> Node);
FreeVecPooled(NodeList);
}
}
Info -> DoneSize = 0;
Info -> DoneFiles = 0;
Info -> CurrentFile = (struct FileTransferNode *)Info -> FileList . mlh_Head;
Info -> CurrentSize = Info -> CurrentFile -> Size;
}
/* BuildFileTransferInfo(struct FileRequester *FileRequester):
*
* Build a file transfer information list from
* information provided by a FileRequester structure.
*/
struct FileTransferInfo * __regargs
BuildFileTransferInfo(struct FileRequester *FileRequester)
{
struct FileTransferInfo *Info;
LONG FilesFound = 0;
if(Info = AllocFileTransferInfo())
{
BYTE Success = FALSE;
BPTR NewLock,
OldLock;
if(NewLock = Lock(FileRequester -> rf_Dir,ACCESS_READ))
{
OldLock = CurrentDir(NewLock);
if(FileRequester -> rf_NumArgs)
{
struct FileInfoBlock *FileInfo;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
BPTR FileLock;
struct WBArg *ArgList = FileRequester -> rf_ArgList;
LONG i;
Success = TRUE;
for(i = 0 ; Success && i < FileRequester -> rf_NumArgs ; i++)
{
if(ArgList[i] . wa_Name)
{
if(ArgList[i] . wa_Lock)
{
CurrentDir(ArgList[i] . wa_Lock);
if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(NameFromLock(FileLock,SharedBuffer,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
UnLock(FileLock);
}
CurrentDir(NewLock);
}
else
{
if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(NameFromLock(FileLock,SharedBuffer,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
UnLock(FileLock);
}
}
}
}
}
FreeDosObject(DOS_FIB,FileInfo);
}
else
{
struct AnchorPath *Anchor;
STRPTR FileName;
if(FileRequester -> rf_NumArgs > 1 && FileRequester -> rf_ArgList)
FileName = FileRequester -> rf_ArgList -> wa_Name;
else
FileName = FileRequester -> rf_File;
if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
{
if(!MatchFirst(FileName,Anchor))
{
Success = TRUE;
if(Anchor -> ap_Info . fib_DirEntryType < 0)
{
if(NameFromLock(NewLock,SharedBuffer,512))
{
if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
if(Success)
{
while(!MatchNext(Anchor))
{
if(NameFromLock(NewLock,SharedBuffer,512))
{
if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
{
Success = FALSE;
break;
}
else
FilesFound++;
}
}
}
}
if(IoErr() != ERROR_NO_MORE_ENTRIES)
Success = FALSE;
}
MatchEnd(Anchor);
FreeVecPooled(Anchor);
}
}
CurrentDir(OldLock);
UnLock(NewLock);
}
if(Success && FilesFound)
{
SortFileTransferInfo(Info);
return(Info);
}
else
FreeFileTransferInfo(Info);
}
return(NULL);
}
/* SendTextFile(STRPTR TheFile):
*
* Send a single text file via xpr.
*/
VOID __regargs
SendTextFile(BYTE Type,STRPTR TheFile)
{
TheFile = ReplaceName(TheFile);
if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
InternalASCIIUpload(TheFile,TRUE);
else
{
BYTE OldStatus = Status;
BPTR NewDir,OldDir;
if(Type == TRANSFER_ASCII)
NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
else
NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
if(NewDir)
OldDir = CurrentDir(NewDir);
else
OldDir = NULL;
Uploading = TRUE;
LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
/* If not initialized, try to set up a new
* external transfer protocol.
*/
if(!XProtocolBase)
{
if(SelectProtocol(LastXprLibrary,Window))
{
if(ProtocolSetup(FALSE))
{
SaveProtocolOpts();
strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
}
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
XprIO -> xpr_filename = TheFile;
if(TransferPanel(SendQuery[TRANSFER_TEXT]))
{
Status = STATUS_UPLOAD;
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);
if(ReadRequest && WriteRequest)
{
if(XProtocolSend(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
if(TransferFailed || TransferAborted)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(TRUE);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
RestartSerial(FALSE);
}
}
else
SetTransferMenu(FALSE);
if(OldDir)
CurrentDir(OldDir);
if(NewDir)
UnLock(NewDir);
if(SendAbort && UsesZModem)
SerWrite(ZModemCancel,20);
SendAbort = FALSE;
Uploading = FALSE;
if(Config -> CommandConfig -> UploadMacro[0])
SerialCommand(Config -> CommandConfig -> UploadMacro);
DidTransfer = FALSE;
}
}
/* StartXprReceive():
*
* Receive files via xpr.
*/
VOID __regargs
StartXprReceive(BYTE Type,STRPTR Name,BYTE WaitForIt)
{
if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIDownload)
InternalASCIIDownload(Name,WaitForIt);
else
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
BYTE OldStatus = Status;
BPTR NewDir,OldDir;
ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
/* Select the download path. */
switch(Type)
{
case TRANSFER_BINARY:
DownloadPath = Config -> PathConfig -> BinaryDownloadPath;
break;
case TRANSFER_TEXT:
DownloadPath = Config -> PathConfig -> TextDownloadPath;
break;
case TRANSFER_ASCII:
DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
break;
}
if(DownloadPath[0])
{
if(NewDir = Lock(DownloadPath,ACCESS_READ))
OldDir = CurrentDir(NewDir);
else
OldDir = NULL;
}
else
NewDir = OldDir = NULL;
BlockWindows();
/* Set up the library if necessary. */
if(!XProtocolBase)
{
if(SelectProtocol(LastXprLibrary,Window))
{
if(ProtocolSetup(FALSE))
{
SaveProtocolOpts();
strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
}
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
/* Do we need to ask the user for
* the destination file name?
*/
if(TransferBits & XPRS_NORECREQ)
{
/* Obviously not, let's open
* the transfer info window as
* usual and download the file(s).
*/
if(TransferPanel(ReceiveQuery[Type]))
{
Status = STATUS_DOWNLOAD;
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
/* Receive the data. */
if(ReadRequest && WriteRequest)
{
if(XProtocolReceive(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
/* In case the transfer has been aborted,
* flush the input buffer of dirty data.
*/
if(TransferAborted)
xpr_sflush();
if(TransferAborted || TransferFailed)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
/* Queue another read request. */
RestartSerial(FALSE);
}
}
else
{
if(!Name)
{
if(FileRequest = GetFile(Window,ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
{
/* Save the download path. */
strcpy(DownloadPath,FileRequest -> rf_Dir);
ConfigChanged = TRUE;
/* Install the name of the file to receive. */
XprIO -> xpr_filename = DummyBuffer;
FreeAslRequest(FileRequest);
Name = DummyBuffer;
}
}
else
{
STRPTR Index;
strcpy(DownloadPath,Name);
ConfigChanged = TRUE;
Index = PathPart(DownloadPath);
*Index = 0;
XprIO -> xpr_filename = Name;
}
/* Download the file(s). */
if(Name)
{
/* Open the transfer panel. */
if(TransferPanel(ReceiveQuery[Type]))
{
Status = STATUS_DOWNLOAD;
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
/* Receive the file. */
if(ReadRequest && WriteRequest)
{
if(XProtocolReceive(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
/* In case the transfer has been aborted,
* flush the input buffer of dirty data.
*/
if(TransferAborted)
xpr_sflush();
if(TransferAborted || TransferFailed)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
/* Queue another read
* request.
*/
RestartSerial(FALSE);
}
}
}
}
else
SetTransferMenu(FALSE);
if(OldDir)
CurrentDir(OldDir);
if(NewDir)
UnLock(NewDir);
if(SendAbort && UsesZModem)
SerWrite(ZModemCancel,20);
SendAbort = FALSE;
ReleaseWindows();
DownloadPath = NULL;
DidTransfer = FALSE;
if(WaitForIt)
{
if(Config -> CommandConfig -> DownloadMacro[0])
SerialCommand(Config -> CommandConfig -> DownloadMacro);
}
}
}
/* StartXprSend():
*
* Send files via xpr.
*/
BYTE __regargs
StartXprSend(BYTE Type,BYTE WaitForIt)
{
if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
return(InternalASCIIUpload(NULL,WaitForIt));
else
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
BYTE OldStatus = Status;
STRPTR UploadPath;
BYTE DidSend = TRUE;
BPTR NewDir,OldDir;
LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
/* We are uploading data. */
Uploading = TRUE;
/* Select the upload path. */
switch(Type)
{
case TRANSFER_BINARY:
UploadPath = Config -> PathConfig -> BinaryUploadPath;
break;
case TRANSFER_TEXT:
UploadPath = Config -> PathConfig -> TextUploadPath;
break;
case TRANSFER_ASCII:
UploadPath = Config -> PathConfig -> ASCIIUploadPath;
break;
}
if(UploadPath[0])
{
if(NewDir = Lock(UploadPath,ACCESS_READ))
OldDir = CurrentDir(NewDir);
else
OldDir = NULL;
}
else
NewDir = OldDir = NULL;
BlockWindows();
/* If not initialized, try to set up a new
* external transfer protocol.
*/
if(!XProtocolBase)
{
if(SelectProtocol(LastXprLibrary,Window))
{
if(ProtocolSetup(FALSE))
{
SaveProtocolOpts();
strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
}
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
/* Do we need to use our own file requester or
* will xpr handle this job for us?
*/
if(TransferBits & XPRS_NOSNDREQ)
{
/* Open the transfer info window. */
if(TransferPanel(SendQuery[Type]))
{
Status = STATUS_UPLOAD;
/* Shut up the serial line. */
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
/* Perform upload. */
if(ReadRequest && WriteRequest)
{
if(XProtocolSend(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
if(TransferFailed || TransferAborted)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
/* And request another character. */
RestartSerial(FALSE);
}
}
else
{
/* We will need the file requester to find
* out which file(s) are to be transferred.
* Multiple files and wildcards are
* supported as well as plain file names.
*/
if(FileRequest = GetFile(Window,SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
{
strcpy(UploadPath,FileRequest -> rf_Dir);
ConfigChanged = TRUE;
if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
{
/* Make sure that at least the
* first file gets transferred
* in case the protocol does
* no support batch upload.
*/
XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
if(TransferPanel(SendQuery[Type]))
{
Status = STATUS_UPLOAD;
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
if(ReadRequest && WriteRequest)
{
if(XProtocolSend(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
if(TransferFailed || TransferAborted)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
RestartSerial(FALSE);
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> rf_Dir);
if(FileTransferInfo)
{
FreeFileTransferInfo(FileTransferInfo);
FileTransferInfo = NULL;
}
}
FreeAslRequest(FileRequest);
}
else
DidSend = FALSE;
}
}
else
SetTransferMenu(FALSE);
if(OldDir)
CurrentDir(OldDir);
if(NewDir)
UnLock(NewDir);
if(SendAbort && UsesZModem)
SerWrite(ZModemCancel,20);
SendAbort = FALSE;
ReleaseWindows();
Uploading = FALSE;
if(WaitForIt)
{
if(Config -> CommandConfig -> UploadMacro[0])
SerialCommand(Config -> CommandConfig -> UploadMacro);
}
DidTransfer = FALSE;
return(DidSend);
}
}
/* StartXprSendFromList():
*
* Send files via xpr.
*/
BYTE __regargs
StartXprSendFromList(BYTE Type,BYTE WaitForIt)
{
if(Type == TRANSFER_ASCII && Config -> TransferConfig -> InternalASCIIUpload)
return(InternalASCIIUpload(NULL,WaitForIt));
else
{
BYTE OldStatus = Status,
DidSend = TRUE;
BPTR NewDir,
OldDir;
STRPTR UploadPath;
LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
/* We are uploading data. */
Uploading = TRUE;
switch(Type)
{
case TRANSFER_BINARY:
UploadPath = Config -> PathConfig -> BinaryUploadPath;
break;
case TRANSFER_TEXT:
UploadPath = Config -> PathConfig -> TextUploadPath;
break;
case TRANSFER_ASCII:
UploadPath = Config -> PathConfig -> ASCIIUploadPath;
break;
}
if(UploadPath[0])
{
if(NewDir = Lock(UploadPath,ACCESS_READ))
OldDir = CurrentDir(NewDir);
else
OldDir = NULL;
}
else
NewDir = OldDir = NULL;
BlockWindows();
/* If not initialized, try to set up a new
* external transfer protocol.
*/
if(!XProtocolBase)
{
if(WaitForIt)
{
if(SelectProtocol(LastXprLibrary,Window))
{
if(ProtocolSetup(FALSE))
{
SaveProtocolOpts();
strcpy(Config -> FileConfig -> ProtocolFileName,LastXprLibrary);
}
}
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
/* Make sure that at least the
* first file gets transferred
* in case the protocol does
* no support batch upload.
*/
XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
if(TransferPanel(SendQuery[Type]))
{
Status = STATUS_UPLOAD;
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
if(ReadRequest && WriteRequest)
{
if(XProtocolSend(XprIO))
TransferFailed = FALSE;
else
TransferFailed = TRUE;
}
else
TransferFailed = TRUE;
if(TransferFailed || TransferAborted)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
Status = OldStatus;
RestartSerial(FALSE);
}
if(FileTransferInfo)
{
FreeFileTransferInfo(FileTransferInfo);
FileTransferInfo = NULL;
}
}
else
{
SetTransferMenu(FALSE);
DidSend = FALSE;
}
if(OldDir)
CurrentDir(OldDir);
if(NewDir)
UnLock(NewDir);
if(SendAbort && UsesZModem)
SerWrite(ZModemCancel,20);
SendAbort = FALSE;
ReleaseWindows();
Uploading = FALSE;
if(WaitForIt)
{
if(Config -> CommandConfig -> UploadMacro[0])
SerialCommand(Config -> CommandConfig -> UploadMacro);
}
DidTransfer = FALSE;
return(DidSend);
}
}
/* ChangeProtocol(STRPTR ProtocolName):
*
* Select a different file transfer protocol.
*/
BYTE __regargs
ChangeProtocol(STRPTR ProtocolName)
{
UBYTE NameBuffer[40],i;
if(!ProtocolName || !ProtocolName[0])
ProtocolName = Config -> TransferConfig -> DefaultLibrary;
if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
return(TRUE);
/* Close the old library if still open. */
if(XProtocolBase)
{
XProtocolCleanup(XprIO);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
SetTransferMenu(FALSE);
}
/* Clear the XPR interface buffer. */
memset(XprIO,0,sizeof(struct XPR_IO));
/* Copy the name of the library. */
strcpy(NameBuffer,FilePart(ProtocolName));
/* Extract the name itself (strip the `.library'). */
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
/* Check if the transfer protocol is a sort of ZModem. */
UsesZModem = FALSE;
for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
{
if(!Stricmp(&NameBuffer[i],"zmodem"))
UsesZModem = TRUE;
}
/* Reset the scanner. */
FlowInit(TRUE);
/* Obtain the protocol default settings. */
if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
ProtocolOptsBuffer[0] = 0;
/* Initialize the interface structure. */
XprIO -> xpr_filename = ProtocolOptsBuffer;
XprIO -> xpr_fopen = xpr_fopen;
XprIO -> xpr_fclose = xpr_fclose;
XprIO -> xpr_fread = xpr_fread;
XprIO -> xpr_fwrite = xpr_fwrite;
XprIO -> xpr_sread = xpr_sread;
XprIO -> xpr_swrite = xpr_swrite;
XprIO -> xpr_sflush = xpr_sflush;
XprIO -> xpr_update = xpr_update;
XprIO -> xpr_chkabort = xpr_chkabort;
XprIO -> xpr_gets = xpr_gets;
XprIO -> xpr_setserial = xpr_setserial;
XprIO -> xpr_ffirst = xpr_ffirst;
XprIO -> xpr_fnext = xpr_fnext;
XprIO -> xpr_finfo = xpr_finfo;
XprIO -> xpr_fseek = xpr_fseek;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = xpr_options;
XprIO -> xpr_unlink = xpr_unlink;
XprIO -> xpr_squery = xpr_squery;
XprIO -> xpr_getptr = xpr_getptr;
/* Try to open the library. */
if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
{
/* Set up the library. */
ClearSerial();
TransferBits = XProtocolSetup(XprIO);
RestartSerial(FALSE);
DeleteTransferPanel(TRUE);
/* Successful initialization? */
if(TransferBits & XPRS_SUCCESS)
{
SetTransferMenu(TRUE);
strcpy(LastXprLibrary,ProtocolName);
if(TransferBits & XPRS_HOSTMON)
ConTransfer = ConTransferHost;
else
ConTransfer = ConProcess;
if(TransferBits & XPRS_HOSTNOWAIT)
{
if(!HostReadBuffer)
HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
}
else
{
if(HostReadBuffer)
{
FreeVecPooled(HostReadBuffer);
HostReadBuffer = NULL;
}
}
return(TRUE);
}
else
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
SetTransferMenu(FALSE);
LastXprLibrary[0] = 0;
TransferBits = 0;
ConTransfer = ConProcess;
}
}
else
{
ConTransfer = ConProcess;
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),ProtocolName);
}
return(FALSE);
}
/* ResetProtocol():
*
* Return to the previously selected file
* transfer protocol.
*/
VOID
ResetProtocol()
{
ChangeProtocol(NULL);
}
/* ProtocolSetup(BYTE IgnoreOptions):
*
* Set up the library and options for the external protocol.
*/
BYTE __regargs
ProtocolSetup(BYTE IgnoreOptions)
{
UBYTE NameBuffer[40],i;
/* Close the old library if still open. */
if(XProtocolBase)
{
XProtocolCleanup(XprIO);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
SetTransferMenu(FALSE);
}
/* Clear the XPR interface buffer. */
memset(XprIO,0,sizeof(struct XPR_IO));
/* Copy the name of the library. */
strcpy(NameBuffer,FilePart(LastXprLibrary));
/* Extract the name itself (strip the `.library'). */
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
/* Check if the transfer protocol is a sort of ZModem. */
UsesZModem = FALSE;
for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
{
if(!Stricmp(&NameBuffer[i],"zmodem"))
UsesZModem = TRUE;
}
/* Reset the scanner. */
FlowInit(TRUE);
/* Obtain the protocol default settings. */
if(!IgnoreOptions)
{
if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
ProtocolOptsBuffer[0] = 0;
}
/* Initialize the interface structure. */
XprIO -> xpr_filename = ProtocolOptsBuffer;
XprIO -> xpr_fopen = xpr_fopen;
XprIO -> xpr_fclose = xpr_fclose;
XprIO -> xpr_fread = xpr_fread;
XprIO -> xpr_fwrite = xpr_fwrite;
XprIO -> xpr_sread = xpr_sread;
XprIO -> xpr_swrite = xpr_swrite;
XprIO -> xpr_sflush = xpr_sflush;
XprIO -> xpr_update = xpr_update;
XprIO -> xpr_chkabort = xpr_chkabort;
XprIO -> xpr_gets = xpr_gets;
XprIO -> xpr_setserial = xpr_setserial;
XprIO -> xpr_ffirst = xpr_ffirst;
XprIO -> xpr_fnext = xpr_fnext;
XprIO -> xpr_finfo = xpr_finfo;
XprIO -> xpr_fseek = xpr_fseek;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = xpr_options;
XprIO -> xpr_unlink = xpr_unlink;
XprIO -> xpr_squery = xpr_squery;
XprIO -> xpr_getptr = xpr_getptr;
/* Try to open the library. */
if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
{
/* Set up the library. */
ClearSerial();
TransferBits = XProtocolSetup(XprIO);
RestartSerial(FALSE);
DeleteTransferPanel(IgnoreOptions != TRUE);
/* Successful initialization? */
if(TransferBits & XPRS_SUCCESS)
{
SetTransferMenu(TRUE);
if(TransferBits & XPRS_HOSTMON)
ConTransfer = ConTransferHost;
else
ConTransfer = ConProcess;
if(TransferBits & XPRS_HOSTNOWAIT)
{
if(!HostReadBuffer)
HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
}
else
{
if(HostReadBuffer)
{
FreeVecPooled(HostReadBuffer);
HostReadBuffer = NULL;
}
}
return(TRUE);
}
else
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
LastXprLibrary[0] = 0;
TransferBits = 0;
ConTransfer = ConProcess;
SetTransferMenu(FALSE);
}
}
else
{
ConTransfer = ConProcess;
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
}
return(FALSE);
}
/* SaveProtocolOpts():
*
* Save the current protocol settings to an environment variable.
*/
VOID
SaveProtocolOpts()
{
/* It's time to save the altered options. */
if(NewOptions && XProtocolBase)
{
UBYTE NameBuffer[40],i;
/* Strip the `.library' part. */
strcpy(NameBuffer,FilePart(LastXprLibrary));
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
/* Cause the xpr.library to prompt for
* input. We expect the library to fill
* the prompt string with the default
* settings. The resulting string is
* intercepted by xpr_stealopts, saved
* to an environment variable and will
* serve as a reinitialization string
* later.
*/
XprIO -> xpr_filename = NULL;
XprIO -> xpr_gets = xpr_stealopts;
XprIO -> xpr_extension = 0;
XprIO -> xpr_options = NULL;
ClearSerial();
XProtocolSetup(XprIO);
DeleteTransferPanel(FALSE);
/* Save the options in case anything goes
* wrong.
*/
NewOptions = FALSE;
SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
/* Reinitialize the library. */
XprIO -> xpr_filename = ProtocolOptsBuffer;
XprIO -> xpr_gets = xpr_gets;
XprIO -> xpr_extension = 4;
XprIO -> xpr_options = xpr_options;
XProtocolSetup(XprIO);
RestartSerial(FALSE);
DeleteTransferPanel(FALSE);
}
}
/* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
*
* Select a different transfer protocol library using
* the asl.library file requester.
*/
BYTE __regargs
SelectProtocol(STRPTR Name,struct Window *ParentWindow)
{
strcpy(SharedBuffer,LastXprLibrary);
if(PickFile(Window,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),SharedBuffer,NT_LIBRARY))
{
if(Stricmp(SharedBuffer,LastXprLibrary))
{
strcpy(LastXprLibrary,SharedBuffer);
return(TRUE);
}
}
return(FALSE);
}
/* TransferCleanup():
*
* We did a file transfer (auto-download?) and
* will need to close the transfer window.
*/
VOID
TransferCleanup()
{
if(DidTransfer)
{
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(TRUE);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
if(SendAbort && UsesZModem)
SerWrite(ZModemCancel,20);
SendAbort = FALSE;
if(Config -> CommandConfig -> DownloadMacro[0])
SerialCommand(Config -> CommandConfig -> DownloadMacro);
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
DidTransfer = FALSE;
}
else
{
if(TransferFailed || TransferError)
{
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(TRUE);
}
else
{
if(TransferWindow)
{
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
WaitTime(2,0);
}
DeleteTransferPanel(FALSE);
}
}
BinaryTransfer = TRUE;
Status = STATUS_READY;
ReleaseWindows();
}
/* RemoveUploadListItem(STRPTR Name):
*
* Remove a named item from the upload list.
*/
VOID __regargs
RemoveUploadListItem(STRPTR Name)
{
BPTR NameLock;
if(NameLock = Lock(Name,ACCESS_READ))
{
struct GenericList *List = GenericListTable[GLIST_UPLOAD];
struct Node *Node;
STRPTR Base = FilePart(Name);
ObtainSemaphore(&List -> ListSemaphore);
Node = (struct Node *)List -> ListHeader . mlh_Head;
while(Node -> ln_Succ)
{
if(!Stricmp(Base,FilePart(Node -> ln_Name)))
{
BPTR ListLock;
if(ListLock = Lock(Node -> ln_Name,ACCESS_READ))
{
if(SameLock(ListLock,NameLock) == LOCK_SAME)
{
Forbid();
ReleaseSemaphore(&List -> ListSemaphore);
DeleteGenericListNode(List,Node);
Permit();
UnLock(ListLock);
UnLock(NameLock);
return;
}
UnLock(ListLock);
}
}
Node = Node -> ln_Succ;
}
ReleaseSemaphore(&List -> ListSemaphore);
UnLock(NameLock);
}
}